package wmysql

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

type WReport struct {
	db *sql.DB
}

type CampaignHourReport struct {
	CampaignId   int
	AdvertiserId int
	PublisherId  int
	Os           string
	YyyymmddHH   int
	Click        int
	Install      int
	InstallOut   int
	Revenue      float64
	RevenueOut   float64
}

type InsCli struct {
	CampaignId   int
	AdvertiserId int
	Os           string
	OsVersion    string
	PublisherId  int
	DeviceType   string
	Ip           string
	Idfa         string
	IdfaMd5      string
	Imei         string
	ImeiMd5      string
	Gaid         string
	GaidMd5      string
	AndroidId	 string
	AndroidIdMd5 string
	ClickId      string
	Insts        int64
	Clits        int64
	Siteid       string
	Price        float64
	PriceOut     float64
	CutRate      float64
	Cut          int
}

func (r *WReport) Init(uri string, maxIdleConn int, maxOpenConn int) error {
	db, err := sql.Open("mysql", uri)
	if err != nil {
		return err
	}
	db.SetMaxOpenConns(maxOpenConn)
	db.SetMaxIdleConns(maxIdleConn)
	if err := db.Ping(); err != nil {
		return err
	}
	r.db = db
	return nil
}

func (r *WReport) InsertInscli(i *InsCli) (int64, error) {
	res, err := r.db.Exec(
		`INSERT INTO inscli
	   (campaign_id, advertiser_id, os, osversion, publisher_id, device_type, ip, idfa, idfa_md5, imei, imei_md5, gaid, gaid_md5, android_id, android_id_md5, click_id, insts, clits, site_id, price, price_out, cut_rate, cut) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON DUPLICATE KEY UPDATE campaign_id = ?, advertiser_id = ?, os = ?, osversion = ?, publisher_id = ?, device_type = ?, ip = ?, insts = ?, clits = ?, cut = ?, cut_rate = ?, price = ?, price_out = ?`,
		i.CampaignId, i.AdvertiserId, i.Os, i.OsVersion, i.PublisherId, i.DeviceType, i.Ip, i.Idfa, i.IdfaMd5, i.Imei, i.ImeiMd5, i.Gaid, i.GaidMd5, i.AndroidId, i.AndroidIdMd5, i.ClickId, i.Insts, i.Clits, i.Siteid, i.Price, i.PriceOut, i.CutRate, i.Cut,
		i.CampaignId, i.AdvertiserId, i.Os, i.OsVersion, i.PublisherId, i.DeviceType, i.Ip, i.Insts, i.Clits, i.Cut, i.CutRate, i.Price, i.PriceOut,
	)
	if err != nil {
		return 0, err
	}
	return res.RowsAffected()
}

func (r *WReport) InsertCampaignHourReport(c *CampaignHourReport) (int64, error) {
	res, err := r.db.Exec(
		`INSERT INTO campaign_hour_report
		(campaign_id, advertiser_id, os, publisher_id, yyyymmddhh, click, install, install_out, revenue, revenue_out) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON DUPLICATE KEY UPDATE click = ?, install = ?, install_out = ?, revenue = ?, revenue_out = ?`,
		c.CampaignId, c.AdvertiserId, c.Os, c.PublisherId, c.YyyymmddHH, c.Click, c.Install, c.InstallOut, c.Revenue, c.RevenueOut,
		c.Click, c.Install, c.InstallOut, c.Revenue, c.RevenueOut,
	)
	if err != nil {
		return 0, err
	}
	return res.RowsAffected()
}

func (r *WReport) SelectInsCliByClickId(clickid string) (*InsCli, error) {
	i := &InsCli{}
	row := r.db.QueryRow(`SELECT campaign_id, advertiser_id, os, osversion, publisher_id, device_type, ip, idfa, idfa_md5, imei, imei_md5, gaid, gaid_md5, android_id, android_id_md5, click_id, insts, clits, site_id, price, price_out, cut_rate, cut FROM inscli WHERE click_id = ?`, clickid)
	if err := row.Scan(&i.CampaignId, &i.AdvertiserId, &i.Os, &i.OsVersion, &i.PublisherId, &i.DeviceType, &i.Ip, &i.Idfa, &i.IdfaMd5, &i.Imei, &i.ImeiMd5, &i.Gaid, &i.GaidMd5, &i.AndroidId, &i.AndroidIdMd5, &i.ClickId, &i.Insts, &i.Clits, &i.Siteid, &i.Price, &i.PriceOut, &i.CutRate, &i.Cut); err != nil {
		return nil, err
	}

	return i, nil
}

func (r *WReport) SelectCampaignHourReportByCidDate(cid int, pid int, yyyymmddhh int) (*CampaignHourReport, error) {
	c := &CampaignHourReport{}
	row := r.db.QueryRow(`SELECT campaign_id, advertiser_id, publisher_id, yyyymmddhh, click, install, install_out, revenue, revenue_out FROM campaign_hour_report WHERE campaign_id = ? AND publisher_id = ? AND yyyymmddhh = ?`, cid, pid, yyyymmddhh)
	if err := row.Scan(&c.CampaignId, &c.AdvertiserId, &c.PublisherId, &c.YyyymmddHH, &c.Click, &c.Install, &c.InstallOut, &c.Revenue, &c.RevenueOut); err != nil {
		return nil, err
	}

	return c, nil
}

func (r *WReport) DeleteInsCliByClickId(clickid string) (int64, error) {
	res, err := r.db.Exec(`DELETE FROM inscli WHERE clickid = ?`, clickid)
	if err != nil {
		return 0, err
	}
	return res.RowsAffected()
}

func (r *WReport) DeleteCampaignHourReportByCidDate(cid int, pid int, yyyymmddhh int) (int64, error) {
	res, err := r.db.Exec(`DELETE FROM campaign_hour_report WHERE campaign_id = ? AND publisher_id = ? AND yyyymmddhh = ?`, cid, pid, yyyymmddhh)
	if err != nil {
		return 0, err
	}
	return res.RowsAffected()
}
